module ysyx_050369_clint (
    input        clk,
    input        rst,
    input        i_timer_valid,
    input        pc_stop,
    input [31:0] mem_waddr,
    input [63:0] mem_wdata,
    input        mem_wen,
    input [3:0]  mem_wmask,
    input [31:0] mem_raddr,
    output reg[63:0] mem_rdata,
    output       time_intr,
    output       msip_valid
);
    reg [63:0] CtMask;

    reg [63:0] mtimecmp;
    reg [63:0] mtime;
    reg [31:0] msip;
    // wire mie;
    // assign mie = i_mstatus[3];
    assign msip_valid = msip[0];
    always @(posedge clk ) begin
        if (rst) begin
            mtimecmp <= 64'b0;
            mtime    <= 64'b0;
            msip     <= 32'b0;
        end
        else begin
            if (mem_wen) begin
                case (mem_waddr)
                    `ysyx_050369_msip    : msip     <= {msip[31:1],mem_wdata[0] & CtMask[0]};
                    `ysyx_050369_mtimecmp: mtimecmp <= mem_wdata & CtMask;
                    `ysyx_050369_mtime:    mtime    <= mem_wdata & CtMask;
                    default: begin      end
                endcase
            end
            else begin
                if (time_intr && ~pc_stop && i_timer_valid) begin
                    mtime <='b0;
                end
                else if (i_timer_valid) begin
                    mtime <= mtime + 1;
                end
            end
        end
    end
    always @(*) begin
        case (mem_raddr)
            `ysyx_050369_msip    : mem_rdata = {32'b0,msip};
            `ysyx_050369_mtimecmp: mem_rdata = mtimecmp;
            `ysyx_050369_mtime   : mem_rdata =  mtime;
            default: mem_rdata =  'b0;
        endcase
    end
    // MuxKeyWithDefault #(3, 32, 64) mem_rdata_choose (mem_rdata, mem_raddr, 64'h0, {
    //     `ysyx_050369_msip    , {32'b0,msip}     ,
    //     `ysyx_050369_mtimecmp, mtimecmp ,
    //     `ysyx_050369_mtime   , mtime    
    // });
    assign time_intr = mtime > mtimecmp;
    always @(*) begin
        case (mem_wmask[3:0])
            4'h1 :CtMask = 64'h0000_0000_0000_00ff;
            4'h3 :CtMask = 64'h0000_0000_0000_ffff;
            4'h7 :CtMask = 64'h0000_0000_ffff_ffff;
            4'hf :CtMask = 64'hffff_ffff_ffff_ffff;
            default:CtMask = 64'hffff_ffff_ffff_ffff;
        endcase
    end
endmodule